package es.uc3m.setichat.android.activity;

import java.io.BufferedReader;
import java.io.DataInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStreamReader;

import es.uc3m.setichat.android.R;
import es.uc3m.setichat.android.SeTIChatCertificatesController;
import es.uc3m.setichat.android.SeTIChatSQLiteHelper;
import es.uc3m.setichat.android.SeTIChatService;
import es.uc3m.setichat.android.SeTIChatXMLController;
import es.uc3m.setichat.android.SeTIChatXMPPController;
import es.uc3m.setichat.utils.Base64;
import android.app.Activity;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteStatement;
import android.os.Bundle;
import android.os.Environment;
import android.os.IBinder;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;

public class SeTIChatCertificatesSettings extends Activity{
	
	private boolean DEBUG = false;
	private SeTIChatService mBoundService;
	private static SeTIChatCertificatesSettings act = null; 
	
	private ServiceConnection mConnection = new ServiceConnection() {
		public void onServiceConnected(ComponentName className, IBinder service) {
	        // This is called when the connection with the service has been
	        // established, giving us the service object we can use to
	        // interact with the service.  Because we have bound to a explicit
	        // service that we know is running in our own process, we can
	        // cast its IBinder to a concrete class and directly access it.
	        mBoundService = ((SeTIChatService.LocalBinder)service).getService();
	        
	        DEBUG = mBoundService.getDebug();
	        
	        if(DEBUG)
	        	Log.d("LoginActivity", "bind service");
	    }

	    public void onServiceDisconnected(ComponentName className) {
	        // This is called when the connection with the service has been
	        // unexpectedly disconnected -- that is, its process crashed.
	        // Because it is running in our same process, we should never
	        // see this happen.
	    	
	    	if(DEBUG)
	        	Log.d("LoginActivity", "onServiceDisconnected: un-bounding the service");
	    	
	    }
	};
	
	@Override
	public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        
        SeTIChatCertificatesSettings.act = this;
        
        setContentView(R.layout.setting_certificates);
  
        Button accept = (Button) findViewById(R.id.save_certificates);
        
        Button download = (Button) findViewById(R.id.download_certificates);
        
        if (mBoundService == null) {
			// Binding the activity to the service to get shared objects
			bindService(new Intent(SeTIChatCertificatesSettings.this,
					SeTIChatService.class), mConnection,
					Context.BIND_AUTO_CREATE);
		}
        
        
        accept.setOnClickListener(new OnClickListener() {
			
			@Override
			public void onClick(View v) {
		        EditText aux = (EditText) findViewById(R.id.path_private_key);
		        String private_key = aux.getText().toString();
		        
		        aux = (EditText) findViewById(R.id.psw_private_key);
		        String psw_private_key = aux.getText().toString();
		        
		        aux = (EditText) findViewById(R.id.path_public_key);
		        String public_key = aux.getText().toString();
		        
		        
		        if(DEBUG){
		        	Log.d("settings-certificates","private key file ="+private_key);
		        	Log.d("settings-certificates","public key file ="+public_key);
		        }
		        
		        String path = Environment.getExternalStorageDirectory().getAbsolutePath();
		        
		        
		        SeTIChatSQLiteHelper setiDB = new SeTIChatSQLiteHelper(mBoundService.getBaseContext(), "BBDDSetichat", null, SeTIChatSQLiteHelper.SQL_VERSION); 
    	        SQLiteDatabase db = setiDB.getWritableDatabase();
    	        if(db!=null){
    	        		FileInputStream iStream = null;
    	        		SQLiteStatement stmt 	= null;
    	        		String base64 			= "";
    	        		byte buffer[] 			= new byte[256];
    	        		byte cert_content[]		= new byte[0];
    	        		int count;
    	        		File file;
    	        		
    	        		try {
							iStream 		= new FileInputStream(path + public_key);
							
							while((count = iStream.read(buffer)) > 0){
								byte aux2[] = new byte[cert_content.length + count];
								System.arraycopy(cert_content, 0, aux2, 0, cert_content.length);
								System.arraycopy(buffer, 0, aux2, cert_content.length, count);
								cert_content = aux2;
							}
							base64 = Base64.encodeToString(cert_content, false);
							
							stmt = db.compileStatement("INSERT INTO user_certificates (type,certificate) VALUES('cer',?)");
	    	        		stmt.bindString(1, base64);
	    	        		
	    	        		db.execSQL("DELETE from user_certificates WHERE type='cer'");
	    	        		stmt.execute();
							
						} catch (FileNotFoundException e) {
							mBoundService.showError("Public key file not found"); 
							return;
						} catch (IOException e) {
							mBoundService.showError("Error"); 
							return;
						}
    	        		
    	        		
    	        		SeTIChatXMLController xml = new SeTIChatXMLController();
    					String random_id = xml.generateRandomID();
    					mBoundService.xmppController.sendMessage(xml.createUpload("cer", base64, random_id),random_id,"upload");
    	        		
    	        		try {
    	        			
							iStream = new FileInputStream(path + private_key);
							cert_content = new byte[0];
							
							while((count = iStream.read(buffer)) > 0){
								byte aux2[] = new byte[cert_content.length + count];
								System.arraycopy(cert_content, 0, aux2, 0, cert_content.length);
								System.arraycopy(buffer, 0, aux2, cert_content.length, count);
								cert_content = aux2;
							}
							base64 = Base64.encodeToString(cert_content, false);
							
							stmt = db.compileStatement("INSERT INTO user_certificates (type,certificate,password) VALUES('p12',?,?)");
	    	        		stmt.bindString(1, base64);
	    	        		stmt.bindString(2, psw_private_key);
	    	        		
	    	        		db.execSQL("DELETE from user_certificates WHERE type='p12'");
	    	        		stmt.execute();
	    	        		
	    	        		SeTIChatCertificatesController.initPrivateKey();
							
						} catch (FileNotFoundException e) {
							mBoundService.showError("Private key file not found"); 
							return;
						} catch (IOException e) {
							mBoundService.showError("Error"); 
							return;
						}
    	        		
    	        		
    	        		random_id = xml.generateRandomID();
    	        		String cert = xml.createUpload("p12", base64, random_id);
    	        		Log.d("cert",cert);
    					mBoundService.xmppController.sendMessage(cert,random_id,"upload");
    					
    					SeTIChatCertificatesSettings.act.finish();
    	        		
    					
    	        		
    	        }
    	        db.close();
    			setiDB.close();
			}
		});
        
        download.setOnClickListener(new OnClickListener() {

			@Override
			public void onClick(View arg0) {
				SeTIChatSQLiteHelper setiDB = new SeTIChatSQLiteHelper(mBoundService.getBaseContext(), "BBDDSetichat", null, SeTIChatSQLiteHelper.SQL_VERSION); 
    	        SQLiteDatabase db = setiDB.getWritableDatabase();
    	        
    	        db.execSQL("DELETE from user_certificates");
    	        
    	        EditText aux = (EditText) findViewById(R.id.psw_private_key);
		        String psw_private_key = aux.getText().toString();
    	        
    	        SQLiteStatement stmt = db.compileStatement("INSERT INTO user_certificates (type,password) VALUES('p12',?)");
        		stmt.bindString(1, psw_private_key);
        		
        		stmt.execute();
        		
        		db.close();
        		setiDB.close();
        		
        		SeTIChatXMLController xml = new SeTIChatXMLController();
				String random_id = xml.generateRandomID();
				mBoundService.xmppController.sendMessage(xml.createCertificateRequest("cer", SeTIChatXMLController.mobile, random_id),random_id,"certificate-request");
				
				random_id = xml.generateRandomID();
				mBoundService.xmppController.sendMessage(xml.createCertificateRequest("p12", SeTIChatXMLController.mobile, random_id),random_id,"certificate-request");
        		
        		SeTIChatCertificatesSettings.act.finish();
    	        
			}
        	
        });

	}
	
	@Override
	protected void onDestroy() {
		
        unbindService(mConnection);
		
		super.onDestroy();
	}
}
